package com.xdb.sqlparser.dialect.sql99.parser;

import com.xdb.sqlparser.ast.SQLName;
import com.xdb.sqlparser.ast.statement.SQLColumnDefinition;
import com.xdb.sqlparser.ast.statement.SQLConstraint;
import com.xdb.sqlparser.ast.statement.SQLCreateTableStatement;
import com.xdb.sqlparser.ast.statement.SQLExprTableSource;
import com.xdb.sqlparser.ast.statement.SQLTableElement;
import com.xdb.sqlparser.exception.ParserException;
import com.xdb.sqlparser.parser.SQLToken;

public class SQL99CreateTableParser extends SQL99StatementParser {

	public SQL99CreateTableParser(String sql) {
		super(sql);
	}

	public SQL99CreateTableParser(SQL99ExprParser exprParser) {
		super(exprParser);
	}

	public SQLCreateTableStatement parseCrateTable() {
		return parseCrateTable(true);
	}

	public SQLCreateTableStatement parseCrateTable(boolean acceptCreate) {
		if (acceptCreate) {
			accept(SQLToken.CREATE);
		}

		SQLCreateTableStatement createTable = newCreateStatement();

		if (identifierEquals("GLOBAL")) {
			lexer.nextToken();

			if (identifierEquals("TEMPORARY")) {
				lexer.nextToken();
				createTable.setType(SQLCreateTableStatement.Type.GLOBAL_TEMPORARY);
			} else {
				throw new ParserException("syntax error " + lexer.token() + " " + lexer.stringVal());
			}
		} else if (lexer.token() == SQLToken.IDENTIFIER && lexer.stringVal().equalsIgnoreCase("LOCAL")) {
			lexer.nextToken();
			if (lexer.token() == SQLToken.IDENTIFIER && lexer.stringVal().equalsIgnoreCase("TEMPORAY")) {
				lexer.nextToken();
				createTable.setType(SQLCreateTableStatement.Type.LOCAL_TEMPORARY);
			} else {
				throw new ParserException("syntax error");
			}
		}

		accept(SQLToken.TABLE);

		createTable.setName(this.exprParser.name());

		if (lexer.token() == SQLToken.LPAREN) {
			lexer.nextToken();

			for (;;) {
				if (lexer.token() == SQLToken.IDENTIFIER //
						|| lexer.token() == SQLToken.LITERAL_ALIAS) {
					SQLColumnDefinition column = this.exprParser.parseColumn();
					createTable.getTableElementList().add(column);
				} else if (lexer.token() == SQLToken.PRIMARY //
						|| lexer.token() == SQLToken.UNIQUE //
						|| lexer.token() == SQLToken.CHECK //
						|| lexer.token() == SQLToken.CONSTRAINT) {
					SQLConstraint constraint = this.exprParser.parseConstaint();
					constraint.setParent(createTable);
					createTable.getTableElementList().add((SQLTableElement) constraint);
				} else if (lexer.token() == SQLToken.TABLESPACE) {
					throw new ParserException("TODO " + lexer.token());
				} else {
					SQLColumnDefinition column = this.exprParser.parseColumn();
					createTable.getTableElementList().add(column);
				}

				if (lexer.token() == SQLToken.COMMA) {
					lexer.nextToken();

					if (lexer.token() == SQLToken.RPAREN) { // compatible for
															// sql
															// server
						break;
					}
					continue;
				}

				break;
			}

			// while
			// (this.tokenList.current().equals(OracleToken.ConstraintToken)) {
			// parseConstaint(table.getConstraints());
			//
			// if (this.tokenList.current().equals(OracleToken.CommaToken))
			// ;
			// lexer.nextToken();
			// }

			accept(SQLToken.RPAREN);

			if (identifierEquals("INHERITS")) {
				lexer.nextToken();
				accept(SQLToken.LPAREN);
				SQLName inherits = this.exprParser.name();
				createTable.setInherits(new SQLExprTableSource(inherits));
				accept(SQLToken.RPAREN);
			}
		}

		return createTable;
	}

	protected SQLCreateTableStatement newCreateStatement() {
		return new SQLCreateTableStatement(getDbType());
	}
}
